﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Legend.Threading
{
    /// <summary>
    /// An ISynchronizationManager implementation that utilizes
    /// the Monitor-class for synchronization.
    /// </summary>
    public class MonitorSynchronizationManager
        : ISynchronizationManager
    {
        private object syncRoot;

        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="syncRoot">The object to use as a lock
        /// in the monitor.</param>
        public MonitorSynchronizationManager(object syncRoot)
        {
            Require.ThatArgument(syncRoot).Named("syncRoot").IsNotNull();
            this.syncRoot = syncRoot;
        }

        /// <summary>
        /// Enters the read lock.
        /// </summary>
        public void EnterReadLock()
        {
            Monitor.Enter(syncRoot);
        }

        /// <summary>
        /// Exits the read lock.
        /// </summary>
        public void ExitReadLock()
        {
            Monitor.Exit(syncRoot);
        }

        /// <summary>
        /// Enters the write lock.
        /// </summary>
        public void EnterWriteLock()
        {
            Monitor.Enter(syncRoot);
        }

        /// <summary>
        /// Exits the write lock.
        /// </summary>
        public void ExitWriteLock()
        {
            Monitor.Exit(syncRoot);
        }

        /// <summary>
        /// Enters an upgradable read lock.
        /// </summary>
        public void EnterUpgradableReadLock()
        {
            Monitor.Enter(syncRoot);
        }

        /// <summary>
        /// Exits an upgradable read lock.
        /// </summary>
        public void ExitUpgradableReadLock()
        {
            Monitor.Exit(syncRoot);
        }

        System.Threading.LockRecursionPolicy ISynchronizationManager.RecursionPolicy
        {
            get 
            {
                return LockRecursionPolicy.SupportsRecursion; 
            }
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, 
        /// releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            // Do nothing
        }
    }
}